angular.module('UCX.Cmis')
.factory "ModelService", (CmisService, $http, Utils, $rootScope)->
  commentOnloading = false
  _root = null
  class Object
    selectTab:'details'
    thumbImg:null
    thumbImgBig:null
    noMoreComments:false
    noMoreActivities:false
    commentsOnLoading:false
    activitiesOnLoading:false
    thumbImgLoaded:false
    isDocument: ()->
      @baseTypeId == 'cmis:document'
    isReadOnlyFolder: ()->
      if @baseTypeId == 'cmis:folder'
        for folder in Utils.readOnlyFolders()
          if @path+"/" == CmisService.path + folder
            return true;

      return false;
    canPreviewLikePdf: ()->
      if @contentStreamMimeType=='application/pdf'
        return true

      return false
    getAces: (SuccessCallback, ErrorCallback, force)->

      if force || !@aces
        _this = this
        CmisService.session.getACL(@id, true).ok (data)->
          _this.aces = (new Ace ace for ace in data.aces)
          SuccessCallback && SuccessCallback()
        .notOk (error)->
          if Utils.handleCmis401Error(error)
            return
          ErrorCallback && ErrorCallback(error)
      else
        SuccessCallback && SuccessCallback()

    getRenditions: (SuccessCallback, ErrorCallback, force)->
      _this = this
      if force || !@renditions
        CmisService.session.getRenditions(@id).ok (data)->
          _this.renditions = data
          _this.getThumbImg(SuccessCallback)
          SuccessCallback && SuccessCallback(data)
        .notOk (error)->
          if Utils.handleCmis401Error(error)
            return
          ErrorCallback && ErrorCallback(error)
      else
        SuccessCallback && SuccessCallback()
    getThumbImg: (SuccessCallback)->
      _this = this
      hasThumb = false
      for thumb in @renditions
        # pdf 的 smx:thumbnail_big_300 是 gif 会动
        if _this.contentStreamMimeType == 'application/pdf'
          if thumb.kind == 'smx:thumbnail_general'
            hasThumb = true
            _this.thumbImg = CmisService.session.getContentStreamURL(_this.id, true,{streamId:thumb.streamId})
            break
        else
          if thumb.kind == 'smx:thumbnail_big_300'
            hasThumb = true
            _this.thumbImg = CmisService.session.getContentStreamURL(_this.id, true,{streamId:thumb.streamId})
            break

      for thumbImgBig in @renditions
        if thumbImgBig.kind == 'smx:thumbnail_big_300'
          hasThumb = true
          url = CmisService.session.getContentStreamURL(_this.id, true,{streamId:thumb.streamId})
          _this.thumbImgBig = CmisService.session.getContentStreamURL(_this.id, true,{streamId:thumbImgBig.streamId})
          break
      if !hasThumb
        _this.thumbImg = ''
        _this.thumbImgBig = ''

    changeTab: (tab)->
      _this=this
      @selectTab = tab
      if tab == 'activity'
        _this.noMoreActivities=false
        @loadActivity()
      else if tab == 'comment'
        _this.noMoreComments=false
        @loadComment()
    getCustomPath: ()->
      path = @path
      if CmisService.path != '/'
        tree = service.tree
        rootFolder = tree[0]
        rootName = rootFolder.name
        path = @path.replace(CmisService.path, '/'+rootName)
      path

    loadActivity: (force = null)->
      return false
      _this = this
      if !_this.activitiesOnLoading && !_this.noMoreActivities
        type = (if @isDocument() then 'document' else 'room')
        if force || !@activities
          _this.noMoreActivities=false
          _this.activitiesOnLoading=true
          id = @id
          if force == true || force == null
            timestamp = ''
          else
            timestamp = force
          $http.get(CmisService.baseUrl+'api/v3/'+type+'/'+id+'/activities?access-token='+CmisService.token+'&timestamp='+timestamp)
          .success (data)->
            if typeof data == 'object' && data.length > 0
              if _this.activities && force != true
                _this.activities = _this.activities.concat (new Activity activity for activity in data)
              else
                _this.activities = (new Activity activity for activity in data)
            else
              _this.noMoreActivities=true
            _this.activitiesOnLoading=false
          .error (error)->
            _this.noMoreActivities=true
            _this.activitiesOnLoading=false
            console.log error

    createActivity: (activity, data)->
      if CmisService.repository != 'fxcld'
        data.room_id = service.getRoomId()
        data.room_name = service.getRoomName()
        _this = this
        @postActivity activity, data, (activityData)->
          parents = _this.getParents()
          for parent in parents
            if parent.id == _this.id
              continue
            if parent.activities
              parent.activities.unshift new Activity activityData
      else
        return false

    postActivity: (activity, data, successCallback)->
      type = (if @isDocument() then 'document' else 'room')
      postData = {
        type: activity
        data: JSON.stringify data
      }
      _this = this
      $http(
        {
          method : 'POST',
          url    : CmisService.baseUrl+'api/v3/'+type+'/'+@id+'/activities?access-token='+CmisService.token,
          data   : postData
        }
      ).then (response)->
        if _this.activities
          _this.activities.unshift new Activity response.data
        successCallback && successCallback(response.data)
      ,
        (error)->
#          Utils.handleTokenError(error.data)
          console.log error
    getParents: ()->
      _this=this
      tree = service.tree
#      if !@parents
      patents = []
      path = @path
      rootFolder = tree[0]
      rootPath = rootFolder.path
      if !path
        return []
      patents.push rootFolder
      if path != rootPath
        index = (if rootPath == '/' then 1 else rootPath.length + 1)
        actualPath = path.substr index

        paths = actualPath.split('/')
        for path in paths
          if !rootFolder.folderList
            continue
          for child in rootFolder.folderList
            fname = child.path.substr(child.path.lastIndexOf('/')+1)
            if fname == path
              if(child.id == '4636f7ff-aff8-4851-af5e-24333c4a614d')
                console.log '###wront####'
                console.log rootFolder
              patents.push child
              rootFolder = child
      if !_this.isDocument() && Utils.currentFolder.path == _this.path
        $rootScope.folderTree=patents
      patents
#    getBreadCrumb: ()->
#      _this = this
#      tree = service.tree
#      patents = []
#      CmisService.session.getObject(_this.id,'latest').ok(
#        (data)->
#          path = data.succinctProperties['cmis:path']
#          rootFolder = tree[0]
#          rootPath = rootFolder.path
#          if !path
#            return []
#          patents.push rootFolder
#          if path != rootPath
#            index = (if rootPath == '/' then 1 else rootPath.length + 1)
#            actualPath = path.substr index
#            paths = actualPath.split('/')
#            for path in paths
#              if !rootFolder.folderList
#                continue
#              for child in rootFolder.folderList
#                fname = child.path.substr(child.path.lastIndexOf('/')+1)
#                if fname == path
#                  patents.push child
#                  rootFolder = child
#          if !_this.isDocument() && $rootScope.currentFolder.path == _this.path
##            console.log('hehehe')
#            $rootScope.breadCrumbTree=patents
#          patents
#      ).notOk(
#        ()->
#
#      )
    getParent: ()->
      parents = @getParents()
      if @isDocument()
        parent = parents[parents.length-1]
      else
        if @path == CmisService.path
          return null
        parent = parents[parents.length-2]
      parent

    constructor: (object) ->
      @id = object.succinctProperties['cmis:objectId']
      @updateAttr(object)

    refresh: (successCallback)->
      _this = this
      id = if this.versionSeriesId then this.versionSeriesId else this.id
      CmisService.session.getObject(id,'latest',{
        includeAllowableActions: true
      }).ok (object)->
        _this.updateAttr(object)
        if object['succinctProperties']['cmis:objectId'].indexOf('pwc') == -1
          service.allFiles[_this.id] = null
          delete service.allFiles[_this.id]
          _this.id = object['succinctProperties']['cmis:objectId']
          service.allFiles[_this.id] = _this
        successCallback && successCallback()

    loadComment: (force = null)->
      return false
      _this = this
      if !_this.commentsOnLoading && !_this.noMoreComments
#        if it is onloading then
        type = (if @isDocument() then 'document' else 'room')
        if force || !@comments
          _this.commentsOnLoading=true
          _this.noMoreComments=false
          id = @id
          if force == true || force == null
            timestamp = ''
          else
            timestamp = force
          $http.get(CmisService.baseUrl+'api/v3/'+type+'/'+id+'/comment?access-token='+CmisService.token+'&timestamp='+timestamp)
          .success (data)->
            if data.length
              if _this.comments && force != true
                _this.comments = _this.comments.concat (new Comment comment for comment in data)
              else
                _this.comments = (new Comment comment for comment in data)
#                notice this place may cause some problem it has some logic problems
              _this.commentsOnLoading=false
            else
#             property should delay
              _this.noMoreComments=true
              _this.commentsOnLoading=false
          .error (error)->
            _this.commentsOnLoading=false
#            Utils.handleTokenError(error)
            console.log error
      else
        return false

    postComment: (content, successCallback, errorCallback)->
      return false
      type = (if @isDocument() then 'document' else 'room')
      postData = {
        content: content
      }
      _this = this
      $http(
        {
          method : 'POST',
          url    : CmisService.baseUrl+'api/v3/'+type+'/'+@id+'/comment?access-token='+CmisService.token,
          data   : postData
        }
      ).then (response)->
        if _this.comments
          _this.comments.unshift new Comment response.data
        else
          _this.comments = [new Comment response.data]
        successCallback && successCallback()
        _this.noMoreComments=false
      ,
      (error)->
#        Utils.handleTokenError(error.data)
        errorCallback && errorCallback()
#       choseFile.comments
  class Comment
    constructor: (object) ->
      @create_time = object.create_time
      @user_id = object.user_id
      @user = service.getUser @user_id
      @document_id = object.document_id
      @content = object.content

  class Activity
    constructor: (object) ->
      @content = object.content.replace(/<.*?>/g,'')
      @create_time_custom = object.create_time_custom
      @create_time = object.create_time
      @userId = object.user_id
      @user = service.getUser @userId
      @documentId = object.document_id
      @roomId = object.room_id
      @folderId = object.folder_id
      @microtime = object.microtime
    getObjId: ()->
      if @folderId then @folderId else @documentId
  class Ace
    constructor: (object) ->
      @userId = object.principal.principalId
      @permission = object.permissions.join('/')
      @isDirect = object.isDirect
      @user = service.getUser @userId
      @hasRead = null

  class Folder extends Object
    children: null
    updateAttr: (object)->
      @parentId = object.succinctProperties['cmis:parentId']
      @name = object.succinctProperties['cmis:name']
      @path = object.succinctProperties['cmis:path']
      @createdBy =
        service.getUser(object.succinctProperties['cmis:createdBy'])
#        object.succinctProperties['cmis:createdBy']
      @lastModifiedBy =
        service.getUser(object.succinctProperties['cmis:lastModifiedBy'])
#        object.succinctProperties['cmis:lastModifiedBy']
      @creationDate = object.succinctProperties['cmis:creationDate']
      @protectionLevel = object.succinctProperties['smxj:protectionLevel']
      @lastModificationDate =
        object.succinctProperties['cmis:lastModificationDate']
      @baseTypeId =
        object.succinctProperties['cmis:baseTypeId']
      if object.allowableActions
        @allowableActions = object.allowableActions
      else
        @refresh()
      if object.acl
        @aces = (new Ace ace for ace in object.acl.aces when ace.principal.principalId != 'everyone' && ace.permissions[0] != "cmis:all" && ace.principal.principalId != 'guest')
#    属于folder 对象的方法
    isReadonly: ()->
      if CmisService.pluginUi == "pluginList" # PRO-1163 PRO-1640
        return true;
      folderPath = this.path + '/';
      for folder in Utils.readOnlyFolders()
        if folderPath.indexOf(CmisService.path + folder) == 0
          return true;

      return false;

    getChildren: (scope, SuccessCallback, ErrorCallback, force)->
      _this = this
      if force || !@loadChildren || !@lastUpdateTime? || (new Date).valueOf() - @lastUpdateTime > 10000
        CmisService.session.getChildren(@id, {includeACL: true,includeAllowableActions:true,renditionFilter:'*'}).$ok scope, (files)->
#          应该去 对比 last modified date 如果 不同 那么更新 否则 不更新
          _this.lastUpdateTime = (new Date).valueOf()
          _this.loadChildren = true
          _this.children = []
          _this.documentList=[]
          # 没有定义Folder List.
          if !_this.folderList?
            _this.folderList = []
            for document in files.objects
              if document.object.succinctProperties['cmis:baseTypeId'] == 'cmis:document'
                if service.allFiles[document.object.succinctProperties['cmis:objectId']] && document.object.succinctProperties['cmis:lastModificationDate'] == service.allFiles[document.object.succinctProperties['cmis:objectId']].lastModificationDate
                  obj = service.allFiles[document.object.succinctProperties['cmis:objectId']]
                else
                  obj = new Document document.object
#                _this.documentList.push(obj)
                obj.id = obj.versionSeriesId # PRO-1530
              else
                if service.allFiles[document.object.succinctProperties['cmis:objectId']] && document.object.succinctProperties['cmis:lastModificationDate'] == service.allFiles[document.object.succinctProperties['cmis:objectId']].lastModificationDate
                  obj = service.allFiles[document.object.succinctProperties['cmis:objectId']]
                else
                  obj = new Folder document.object
                _this.folderList.push obj
#                service.allFilesIndexOfPath[obj.path] = obj
              _this.children.push obj
              service.allFiles[obj.id] = obj
#              service.allFilesIndexOfPath[obj.path] = obj
          else
            for document in files.objects
              if document.object.succinctProperties['cmis:baseTypeId'] == 'cmis:document'
                if service.allFiles[document.object.succinctProperties['cmis:objectId']] && document.object.succinctProperties['cmis:lastModificationDate'] == service.allFiles[document.object.succinctProperties['cmis:objectId']].lastModificationDate
                  obj = service.allFiles[document.object.succinctProperties['cmis:objectId']]
                else
                  obj = new Document document.object
                #                obj.getRenditions()
                #                _this.documentList.push(obj)
                obj.id = obj.versionSeriesId # PRO-1530
                _this.children.push obj
                service.allFiles[obj.id] = obj
            _this.children = _this.folderList.concat(_this.children)

          SuccessCallback && SuccessCallback()
        .notOk (error)->
          if Utils.handleCmis401Error(error)
            return
          ErrorCallback && ErrorCallback(error)
      else
        SuccessCallback && SuccessCallback()

    isRoot: ()->
      decodeURIComponent(CmisService.path) == @path

  class User
    constructor: (id)->
      @id = id
      @data = null
      @loadDetail()
    loadDetail: (force)->
      _this = this
      if force || !@data
        if @id == 'admin' || @id == 'unknown' || @id == 'everyone' || @id == 'guest'
          return
        $http.get(CmisService.baseUrl+'api/v3/user/'+@id+'?access-token='+CmisService.token+"&host="+window.location.host)
          .success (data)->
            _this.data = data
          .error (error)->
#            Utils.handleTokenError(error)
            _this.data = false
    getName: ()->
      if @data
        if @data.first_name && @data.last_name
          @data.first_name+' '+@data.last_name
        else if @data.first_name
          @data.first_name
        else if @data.last_name
          @data.last_name
        else
          @id
      else
        @id
    getAvatar: ()->
      if @data
        @data.avatar
      else
        if CmisService.isAndroid || CmisService.isIOS
          'img/ananymous-avatar.png'
        else
          '/img/ananymous-avatar.png'

  class Document extends Object
    shardLink:null
    updateAttr: (object) ->
      @name = object.succinctProperties['cmis:name']
      @path = object.succinctProperties['cmis:path']
      @createdBy =
#        object.succinctProperties['cmis:createdBy']
        service.getUser(object.succinctProperties['cmis:createdBy'])
      @lastModifiedBy =
#        object.succinctProperties['cmis:lastModifiedBy']
        service.getUser(object.succinctProperties['cmis:lastModifiedBy'])
      @creationDate =
        object.succinctProperties['cmis:creationDate']
      @lastModificationDate =
        object.succinctProperties['cmis:lastModificationDate']
      @contentStreamFileName =
        object.succinctProperties['cmis:contentStreamFileName']
      @contentStreamId =
        object.succinctProperties['cmis:contentStreamId']
      @contentStreamLength =
        object.succinctProperties['cmis:contentStreamLength']
      @contentStreamMimeType =
        object.succinctProperties['cmis:contentStreamMimeType'].trim()
      @versionSeriesId =
        object.succinctProperties['cmis:versionSeriesId']
      @versionLabel =
        object.succinctProperties['cmis:versionLabel']
      @isMajorVersion =
        object.succinctProperties['cmis:isMajorVersion']
      @isLatestVersion =
        object.succinctProperties['cmis:isLatestVersion']
      @isLatestMajorVersion =
        object.succinctProperties['cmis:isLatestMajorVersion']
      @isVersionSeriesCheckedOut =
        object.succinctProperties['cmis:isVersionSeriesCheckedOut']
      @baseTypeId =
        object.succinctProperties['cmis:baseTypeId']
      @objectTypeId =
        object.succinctProperties['cmis:objectTypeId']
      if object.acl
        @aces = (new Ace ace for ace in object.acl.aces)
      @drmKey = if object.succinctProperties['smxj:drmKey'] then object.succinctProperties['smxj:drmKey'] else ''
      if object.succinctProperties['smxj:freePreviewPages']
        @freePreviewPages = object.succinctProperties['smxj:freePreviewPages']
      if object.allowableActions
        @allowableActions = object.allowableActions
      else
        @refresh()
      @description =
        if object.succinctProperties['cmis:description']
          try
            JSON.parse(object.succinctProperties['cmis:description'])
          catch
            object.succinctProperties['cmis:description']
        else
          object.succinctProperties['cmis:description']
      @sharedLink =
        if @description && @description.shareLink
          @description.shareLink
        else
          ''
      @disableDownload =
        if @description && @description.canDownload!=undefined && @description.canDownload==0
          true
        else
          false

    canPreview: ()->
      if Utils.canPreview(this)
        return true
      else
        return false
    getShareCode: ()->
      if @sharedLink
        index = @sharedLink.lastIndexOf('/')+1
        return @sharedLink.slice(index)
      else
        return false

    getPreviewLink: ()->
      return CmisService.session.getContentStreamURL(@id)


    getVersions: (SuccessCallback, ErrorCallback, force)->
      if force || !@versions
        _this = this
        CmisService.session.getAllVersions(
          @versionSeriesId,
          {objectId:@versionSeriesId}
        ).ok (data)->
          _this.versions = data
          SuccessCallback() if SuccessCallback
        .notOk (error)->
          if Utils.handleCmis401Error(error)
            return
          ErrorCallback(error) if ErrorCallback
      else
        SuccessCallback() if SuccessCallback

    isDrm: ()->
      @objectTypeId == 'smx:drmdoc'

  users = {}

  service = {
    createFolder: (object)->
      folder = new Folder object
      service.allFiles[folder.id] = folder
      folder
    createAce: (object,file)->
      aces = (new Ace ace for ace in object.acl.aces)
      if(file)
        file.aces=aces
      aces

    createDocument: (object)->
      document = new Document object
      service.allFiles[document.id] = document
      document
    getUser: (uid)->
      if !users[uid]
        users[uid] = new User(uid)
      users[uid]
    tree: null
    allFiles: []
    setRoot: (root)->
      _root = root
      @tree = [root]
      @allFiles[root.id] = root
    getObjectById: (id)->
      @allFiles[id]
    getRoomName: ()->
      if _root && _root.path.indexOf('/Shared_Homes/') == 0
        _root.name
      else
        ''
    getRoomId: ()->
      if _root && _root.path.indexOf('/Shared_Homes/') == 0
        _root.id
      else
        ''
    getChildrenFromData: (datas)->
#      console.log('getChildrenFromData',datas)
      children = []
      for object in datas
        folder = service.createFolder object.object.object
        if object.children
          folder.folderList = service.getChildrenFromData object.children
          folder.children = folder.folderList.concat([])
        else
          folder.folderList = []
          folder.children = []
        service.allFiles[folder.id] = folder
        children.push folder
      children
  }
  service